import { Draw } from 'ol/interaction';
import VectorSource from 'ol/source/Vector';
import VectorLayer from 'ol/layer/Vector';
import { Stroke, Style } from 'ol/style';
import { createBox } from 'ol/interaction/Draw';
/**
 * 屏幕截图工具类，提供全图导出和框选区域导出功能
 * @example
 * //底图需要设置跨域属性
  const source = layer?.getSource() as XYZ | WMTS
  source.setTileLoadFunction((tile: any, url) => {
    const image = tile.getImage() as HTMLImageElement
    image.crossOrigin = 'anonymous' // 为每个瓦片设置跨域属性
    image.src = url
  })
 */
export class ScreenShotTool {
    constructor(map) {
        Object.defineProperty(this, "map", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: void 0
        }); // OpenLayers地图实例
        Object.defineProperty(this, "draw", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: void 0
        }); // 绘制交互实例
        Object.defineProperty(this, "drawLayer", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: void 0
        }); // 绘制图层
        Object.defineProperty(this, "selectedArea", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: void 0
        }); // 用户选择的区域
        Object.defineProperty(this, "source", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: new VectorSource()
        }); // 矢量数据源
        this.map = map;
    }
    /**
     * 导出整个地图为PNG图片
     */
    exportMap() {
        if (!this.map)
            return;
        // 获取地图的canvas元素
        const canvas = this.map.getTargetElement().querySelector('canvas');
        // 创建临时canvas
        const tempCanvas = document.createElement('canvas');
        const ctx = tempCanvas.getContext('2d');
        // 设置临时canvas尺寸与地图canvas一致
        tempCanvas.width = canvas.width;
        tempCanvas.height = canvas.height;
        // 将地图canvas内容绘制到临时canvas
        ctx.drawImage(canvas, 0, 0);
        // 创建下载链接并触发下载
        const link = document.createElement('a');
        link.download = `map_${this.getCurrentTime()}.png`;
        link.href = tempCanvas.toDataURL('image/png');
        link.click();
    }
    /**
     * 开始绘制选择区域
     */
    startDraw() {
        if (!this.map)
            return;
        // 清除现有绘制交互
        if (this.draw) {
            this.map.removeInteraction(this.draw);
        }
        // 设置绘制样式
        const style = new Style({
            stroke: new Stroke({
                color: 'rgba(0, 255, 0, 1)', // 绿色描边
                width: 2 // 描边宽度
            })
        });
        // 初始化或重置绘制图层
        if (!this.drawLayer) {
            this.drawLayer = new VectorLayer({
                source: this.source,
                style
            });
            this.drawLayer.set('id', 'drawLayer');
            this.map.addLayer(this.drawLayer);
        }
        else {
            this.drawLayer.getSource()?.clear();
        }
        // 创建矩形绘制交互
        this.draw = new Draw({
            source: this.source,
            type: 'Circle', // 使用Circle类型但通过geometryFunction转换为矩形
            geometryFunction: createBox(), // 将绘制转换为矩形
            style
        });
        this.map.addInteraction(this.draw);
        // 绘制结束事件处理
        this.draw.on('drawend', (e) => {
            this.selectedArea = e.feature.getGeometry();
            this.map && this.map.removeInteraction(this.draw);
        });
    }
    /**
     * 导出框选区域的地图为PNG图片
     */
    exportFrameSelected() {
        if (!this.map || !this.selectedArea)
            return;
        let drawLayer = this.drawLayer;
        if (!drawLayer)
            return;
        // 隐藏绘制图层避免出现在截图中
        drawLayer.setVisible(false);
        // 延迟执行确保图层已隐藏
        setTimeout(() => {
            if (!this.map || !this.selectedArea)
                return;
            // 获取地图canvas
            const canvas = this.map.getTargetElement().querySelector('canvas');
            // 创建临时canvas
            const tempCanvas = document.createElement('canvas');
            const ctx = tempCanvas.getContext('2d');
            // 获取选择区域的范围
            const extent = this.selectedArea.getExtent();
            // 转换为像素坐标
            const bottomLeft = this.map.getPixelFromCoordinate([extent[0], extent[1]]); // 左下角
            const topRight = this.map.getPixelFromCoordinate([extent[2], extent[3]]); // 右上角
            // 计算选择区域的宽高
            const width = topRight[0] - bottomLeft[0];
            const height = bottomLeft[1] - topRight[1]; // 注意Y轴方向
            // 设置临时canvas尺寸
            tempCanvas.width = width;
            tempCanvas.height = height;
            // 只绘制选择区域部分
            ctx.drawImage(canvas, bottomLeft[0], // 源x坐标
            topRight[1], // 源y坐标
            width, // 源宽度
            height, // 源高度
            0, // 目标x坐标
            0, // 目标y坐标
            width, // 目标宽度
            height // 目标高度
            );
            // 创建下载链接并触发下载
            const link = document.createElement('a');
            link.download = `map-selection_${this.getCurrentTime()}.png`;
            link.href = tempCanvas.toDataURL('image/png');
            link.click();
            // 恢复绘制图层可见性
            drawLayer.setVisible(true);
        }, 200);
    }
    /**
     * 生成当前时间戳字符串
     * @returns 格式化的时间字符串 (YYYY-MM-DD_HH-mm-ss)
     */
    getCurrentTime() {
        const now = new Date();
        const year = now.getFullYear();
        const month = String(now.getMonth() + 1).padStart(2, '0');
        const day = String(now.getDate()).padStart(2, '0');
        const hours = String(now.getHours()).padStart(2, '0');
        const minutes = String(now.getMinutes()).padStart(2, '0');
        const seconds = String(now.getSeconds()).padStart(2, '0');
        const timestamp = `${year}-${month}-${day}_${hours}-${minutes}-${seconds}`;
        return timestamp;
    }
}
